#include <core/event.h>
#include <core/class.h>
#include <core/kobject.h>
#include <core/kfifo.h>
#include <task.h>
#include <log.h>

class_impl(kfifo_t, kobject_t){};

static uint32_t kfifo_poll(kobject_t *obj)
{
    unsigned int len = fifo_len(dynamic_cast(kfifo_t)(obj)->fifo);

    if (len)
        return 1;
    return 0;
}

constructor(kfifo_t, unsigned int size)
{
    this->fifo = fifo_alloc(size);
    dynamic_cast(kobject_t)(this)->poll = kfifo_poll;
}

void kfifo_write(kfifo_t *kfifo, unsigned char *buf, unsigned int len)
{
    if (kfifo)
    {
        fifo_put(kfifo->fifo, buf, len);
        object_signal(dynamic_cast(kobject_t)(kfifo), KFIFO_SIGNAL_WRITE, 0);
    }
}

int kfifo_read(kfifo_t *kfifo, unsigned char *buf, unsigned int len)
{
    if (kfifo)
    {
        return fifo_get(kfifo->fifo, buf, len);
    }

    return -1;
}

void sys_fifo_write(slot_t slot, unsigned char *buf, unsigned int len)
{
    kfifo_t *kfifo = dynamic_cast(kfifo_t)(slot_get(process_self(), slot));
    kfifo_write(kfifo, buf, len);
}

int sys_fifo_read(slot_t slot, unsigned char *buf, unsigned int len)
{
    kfifo_t *kfifo = dynamic_cast(kfifo_t)(slot_get(process_self(), slot));
    return kfifo_read(kfifo, buf, len);
}

int sys_fifo_create(unsigned int size)
{
    return slot_alloc_install(process_self(), new (kfifo_t, size));
}

void sys_fifo_destory(slot_t slot)
{
}